package com.ruoyi.socket.manager;

import com.ruoyi.socket.config.BinanceProxyConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 代理刷新管理器
 * 管理代理配置的定时刷新和WebSocket连接重建
 */
@Component
@Slf4j
public class ProxyRefreshManager {
    
    @Resource
    private BinanceProxyConfig binanceProxyConfig;
    
    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);
    private volatile long lastProxyRefreshTime = 0;
    private volatile boolean isRefreshing = false;
    
    @PostConstruct
    public void init() {
        if (binanceProxyConfig.isEnabled()) {
            log.info("启动代理刷新管理器");
            startProxyMonitoring();
        } else {
            log.info("代理未启用，代理刷新管理器不启动");
        }
    }
    
    /**
     * 启动代理监控
     */
    private void startProxyMonitoring() {
        // 每分钟检查一次代理配置
        scheduler.scheduleAtFixedRate(() -> {
            try {
                checkAndRefreshProxy();
            } catch (Exception e) {
                log.error("代理监控任务执行失败", e);
            }
        }, 1, 1, TimeUnit.MINUTES);
        
        log.info("代理监控任务已启动，每分钟检查一次");
    }
    
    /**
     * 检查并刷新代理配置
     */
    private void checkAndRefreshProxy() {
        if (isRefreshing) {
            log.debug("代理刷新正在进行中，跳过本次检查");
            return;
        }
        
        if (binanceProxyConfig.isRandomExpired()) {
            log.info("检测到代理配置已过期，开始刷新代理配置");
            refreshProxyAndReconnect();
        } else {
            long remainingMinutes = binanceProxyConfig.getRemainingMinutes();
            if (remainingMinutes <= 5) {
                log.info("代理配置即将过期（剩余{}分钟），准备刷新", remainingMinutes);
            }
        }
    }
    
    /**
     * 刷新代理配置并重连WebSocket
     */
    public void refreshProxyAndReconnect() {
        if (isRefreshing) {
            log.warn("代理刷新正在进行中，忽略重复请求");
            return;
        }
        
        isRefreshing = true;
        
        try {
            log.info("开始刷新代理配置和重连WebSocket");
            
            // 记录旧的代理信息
            String oldProxyInfo = binanceProxyConfig.getProxyInfo();
            
            // 刷新代理配置（会生成新的随机数）
            binanceProxyConfig.refreshRandom();
            
            // 记录新的代理信息
            String newProxyInfo = binanceProxyConfig.getProxyInfo();
            
            log.info("代理配置已更新: {} -> {}", oldProxyInfo, newProxyInfo);
            
            // 异步重连WebSocket连接
            scheduler.schedule(() -> {
                try {
                    reconnectWebSocketConnections();
                } catch (Exception e) {
                    log.error("重连WebSocket失败", e);
                } finally {
                    isRefreshing = false;
                }
            }, 2, TimeUnit.SECONDS);
            
            lastProxyRefreshTime = System.currentTimeMillis();
            
        } catch (Exception e) {
            log.error("刷新代理配置失败", e);
            isRefreshing = false;
        }
    }
    
    /**
     * 重连WebSocket连接
     * 注意：由于模块依赖限制，这里只是记录日志，实际重连需要在应用层处理
     */
    private void reconnectWebSocketConnections() {
        try {
            log.info("代理配置已更新，需要重连WebSocket连接");
            log.info("请手动重启WebSocket连接以应用新的代理配置");
            
            // TODO: 发送事件通知应用层重连WebSocket
            // 由于模块依赖限制，这里不能直接调用WebSocketRunner
            
        } catch (Exception e) {
            log.error("处理WebSocket重连请求失败", e);
            throw e;
        }
    }
    
    /**
     * 手动触发代理刷新
     */
    public void manualRefresh() {
        log.info("手动触发代理刷新");
        scheduler.execute(() -> {
            try {
                refreshProxyAndReconnect();
            } catch (Exception e) {
                log.error("手动代理刷新失败", e);
            }
        });
    }
    
    /**
     * 获取代理刷新状态
     */
    public boolean isRefreshing() {
        return isRefreshing;
    }
    
    /**
     * 获取上次刷新时间
     */
    public long getLastRefreshTime() {
        return lastProxyRefreshTime;
    }
    
    /**
     * 获取代理状态信息
     */
    public String getProxyStatus() {
        StringBuilder status = new StringBuilder();
        status.append("代理启用: ").append(binanceProxyConfig.isEnabled()).append(", ");
        status.append("配置有效: ").append(binanceProxyConfig.isValidConfig()).append(", ");
        status.append("随机数过期: ").append(binanceProxyConfig.isRandomExpired()).append(", ");
        status.append("剩余时间: ").append(binanceProxyConfig.getRemainingMinutes()).append("分钟, ");
        status.append("正在刷新: ").append(isRefreshing);
        
        return status.toString();
    }
    
    /**
     * 关闭代理刷新管理器
     */
    public void shutdown() {
        if (scheduler != null && !scheduler.isShutdown()) {
            scheduler.shutdown();
            try {
                if (!scheduler.awaitTermination(5, TimeUnit.SECONDS)) {
                    scheduler.shutdownNow();
                }
            } catch (InterruptedException e) {
                scheduler.shutdownNow();
                Thread.currentThread().interrupt();
            }
            log.info("代理刷新管理器已关闭");
        }
    }
} 